﻿using Log;
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearRegression;
using NPOI.HSSF.Record.Formula.Functions;
using PLC;
using PLC.Base;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System.Reflection;
using System.Text;



namespace PumpAlgorithm
{
        public struct Data
        {
            double liuliang;
            double jkyl;
            double ckyl;
            double dianya;
            double dianliu;
            double gonglv;
            double zhuansu;
            double wendu;
            double yangcheng;
            double xiaolv;



            int continueNetConnectFailedTime; //持续连接失败次数
            int continueNetConnectSuccessTime;//持续连接成功次数

            public double Liuliang { get => liuliang; set => liuliang = value; }
            public double Jkyl { get => jkyl; set => jkyl = value; }
            public double Ckyl { get => ckyl; set => ckyl = value; }
            public double Dianya { get => dianya; set => dianya = value; }
            public double Dianliu { get => dianliu; set => dianliu = value; }
            public double Gonglv { get => gonglv; set => gonglv = value; }
            public double Zhuansu { get => zhuansu; set => zhuansu = value; }
            public double Wendu { get => wendu; set => wendu = value; }
            public int ContinueNetConnectFailedTime { get => continueNetConnectFailedTime; set => continueNetConnectFailedTime = value; }
            public int ContinueNetConnectSuccessTime { get => continueNetConnectSuccessTime; set => continueNetConnectSuccessTime = value; }
            public double Yangcheng { get => yangcheng; set => yangcheng = value; }
            public double Xiaolv { get => xiaolv; set => xiaolv = value; }
    }

    /// <summary>
    /// 后续根据不同场景将算法功能拆分一下
    /// </summary>
    public class CanonicalAlgorithm
    {
        const Double g = 9.815f;
        const Double KInlet = 0.05;
        const Double KOutlet = 0.05;

        //const Double g = 9.81;
       // const Double KInlet = 0.05;
       // const Double KOutlet = 0.05;
        const Double pamp =    101.325;


        static CanonicalAlgorithm()
         {
          
    }

        public CanonicalAlgorithm()
        { }

        public CanonicalAlgorithm(Double zInlet,
            Double zOutlet,
            Double kInlet,
            Double kOutlet,
            Double dInlet, //进口管径
            Double dOutlet, //出口管径
            Double lInlet,
            Double lOutlet,
            Double efficiency,
            Double stpRotarySpeed)
        {
            this.zInlet =  zInlet;
            this.zOutlet = zOutlet;
            this.dInlet = dInlet;
            this.dOutlet = dOutlet;
            this.lInlet = lInlet;
            this.lOutlet = lOutlet;
            this.kInlet = kInlet;
            this.kOutlet = kOutlet;
            this.efficiency = efficiency;
            this.stpRotarySpeed = stpRotarySpeed;
        }

        /*public CanonicalAlgorithm(Double zInlet,
            Double zOutlet,
            Double kInlet,
            Double kOutlet,
            Double dInlet, //进口管径
            Double dOutlet, //出口管径
            Double lInlet,
            Double lOutlet)
        {
            this.zInlet = zInlet;
            this.zOutlet = zOutlet;
            this.dInlet = dInlet;
            this.dOutlet = dOutlet;
            this.lInlet = lInlet;
            this.lOutlet = lOutlet;
        }*/




        public void setplcEnvData(EnvData data)
        {

            this.TMedia = data.Temperature;
            this.PresureIn = data.PresureIn;
            this.PresureOut = data.PresureOut;
            this.PowerIn = data.ShaftPower;
            this.WorkQ = data.Flow;
            this.WorkRotarySpeed = data.Speed;
            //this.cc
        }

        #region 私有变量区

        #region 新增计算字段
        private double _teta;
        private double _tau;
        private double _rho;
        private double _aInlet;
        private double _aOutlet;
        private double _eInlet;
        private double _eOutlet;
        private double _vInlet;
        private double _vOutlet;
        private double _reyInlet;
        private double _reyOutlet;
        private double _fInlet;
        private double _fOutlet;
        private double _stpQ;
        private double _workingGeoHead;
        private double _workingFrictionHead;
        private double _workingDynamicHead;
        private double _workingStaticHead;
        private double _workingHead;
        private double _totalPressure;
        private double _stpHead;
        private double _stpPowerIn;
        private double _workingShaftPower;
        private double _stpShaftPower;
        private double _workingWaterPower;
        private double _workingPumpEfficiency;
        private double _stpWaterPower;
        private double _stpPumpEfficiency;
        private double _stpGroupEfficiency;
        private double _npsh;
        private double _headForNpsh;
        private double _stpPresure;
        #endregion

        Double tMedia = 0.0f;
        Double presureOut = 0.0f;
        Double presureIn = 0.0f;

        Double powerIn = 0.0f;
        Double efficiency = 0.0f;



        // 出口高度
        Double zOutlet;
        // 进口高度
        Double zInlet;


        // 出口取压长度
        Double lOutlet;
        // 出口直径
        Double dOutlet;
        // 入口取压长度
        Double lInlet;
        // 入口直径
        Double dInlet;
        // 进口粗糙度
        Double kInlet;
        // 出口粗糙度
        Double kOutlet;


        // 标况转速
        Double stpRotarySpeed;
        // 工况转速
        Double workRotarySpeed;

        // 工况流量
        Double workQ;
    
        #endregion

        #region 通过PLC获取

        /// <summary>
        /// 温度，通过PLC读取
        /// </summary>
        public Double TMedia { get => tMedia; set => tMedia = value; }

        /// <summary>
        /// 出口压力(工况)，通过PLC读取
        /// </summary>
        private Double PresureOut { get => presureOut; set => presureOut = value; }

        /// <summary>
        /// 进口压力(工况)，通过PLC读取
        /// </summary>
        private Double PresureIn { get => presureIn; set => presureIn = value; }

        /// <summary>
        /// 输入功率(工况)，通过PLC读取
        /// </summary>
        public Double PowerIn { get => powerIn; set => powerIn = value; }

        /// <summary>
        /// 当前工况下的流量，通过PLC获取到
        /// </summary>
        public double WorkQ { get => workQ; set => workQ = value; }

        /// <summary>
        /// 工况转速，PLC获取
        /// </summary>
        public double WorkRotarySpeed { get => workRotarySpeed; set => workRotarySpeed = value; }

        #endregion

        #region 每个试验前需要录入的参数
        /// <summary>
        /// 出口取压孔高度,每个试验前录入
        /// </summary>
        public double ZOutlet { get => zOutlet; set => zOutlet = value; }
        /// <summary>
        /// 入口取压孔高度，每个试验前录入
        /// </summary>
        public double ZInlet { get => zInlet; set => zInlet = value; }


        /// <summary>
        /// 出口直径,单位是mm，每个试验前录入
        /// </summary>
        public double DOutlet { get => dOutlet; set => dOutlet = value; }

        /// <summary>
        /// 入口直径,单位是mm，每个试验前录入
        /// </summary>        
        public double DInlet { get => dInlet; set => dInlet = value; }



        /// <summary>
        /// 出口取压长度，每个试验前录入
        /// </summary>
        public double LOutlet { get => lOutlet; set => lOutlet = value; }
        /// <summary>
        /// 入口取压长度，每个试验前录入
        /// </summary>
        public double LInlet { get => lInlet; set => lInlet = value; }




        /// <summary>
        /// 电机效率，每个试验前录入
        /// </summary>
        public double Efficiency { get => efficiency; }

        /// <summary>
        ///  标况转速,试验前设置
        /// </summary>
        public double StpRotarySpeed { get => stpRotarySpeed; }

        #endregion

      

        #region 计算属性（带详细注释）
        /// <summary>
        /// 温度参数θ，无量纲，计算公式：(TMedia + 273.15) / 647.14
        /// 其中647.14为水的临界温度(K)
        /// </summary>
        public Double Teta => _teta;

        /// <summary>
        /// 温度参数τ，无量纲，计算公式：1 - θ
        /// </summary>
        public Double Tau => _tau;

        /// <summary>
        /// 介质密度(kg/m³)，基于IAPWS-IF97公式计算
        /// 计算公式：322*(1 + 1.99602*τ^(1/3) + 1.10123*τ^(2/3) - 0.512506*τ^(5/3) - ...)
        /// </summary>
        public Double Rho => _rho;

        /// <summary>
        /// 进口截面积(m²)，计算公式：π/4 * DInlet²
        /// </summary>
        public Double AInlet => _aInlet;

        /// <summary>
        /// 出口截面积(m²)，计算公式：π/4 * DOutlet²
        /// </summary>
        public Double AOutlet => _aOutlet;

        /// <summary>
        /// 进口相对粗糙度，无量纲，计算公式：KInlet / DInlet
        /// </summary>
        public Double EInlet => _eInlet;

        /// <summary>
        /// 出口相对粗糙度，无量纲，计算公式：KOutlet / DOutlet
        /// </summary>
        public Double EOutlet => _eOutlet;

        /// <summary>
        /// 进口流速(m/s)，计算公式：(WorkQ/3600)/AInlet
        /// 其中WorkQ单位为m³/h，除以3600转换为m³/s
        /// </summary>
        public Double VInlet => _vInlet;

        /// <summary>
        /// 出口流速(m/s)，计算公式：(WorkQ/3600)/AOutlet
        /// </summary>
        public Double VOutlet => _vOutlet;

        /// <summary>
        /// 进口雷诺数，无量纲，计算公式：(DInlet * VInlet)/ν
        /// 其中ν=0.000001为水的运动粘度(m²/s)
        /// </summary>
        public Double ReyInlet => _reyInlet;

        /// <summary>
        /// 出口雷诺数，无量纲，计算公式：(DOutlet * VOutlet)/ν
        /// </summary>
        public Double ReyOutlet => _reyOutlet;

        /// <summary>
        /// 进口摩擦系数，无量纲，使用Colebrook公式计算：
        /// 1/[1.8*log10(6.9/ReyInlet + (EInlet/3.7)^1.11)]²
        /// </summary>
        public Double FInlet => _fInlet;

        /// <summary>
        /// 出口摩擦系数，无量纲，计算同FInlet
        /// </summary>
        public Double FOutlet => _fOutlet;

        /// <summary>
        /// 标况流量(m³/h)，按转速比例换算：
        /// (StpRotarySpeed/WorkRotarySpeed) * WorkQ
        /// </summary>
        public Double StpQ => _stpQ;

        /// <summary>
        /// 工况几何扬程(m)，计算公式：ZOutlet - ZInlet
        /// 表示进出口的高度差
        /// </summary>
        public Double WorkingGeoHead => _workingGeoHead;

        /// <summary>
        /// 工况摩擦损失扬程(m)，计算公式：
        /// FOutlet*(LOutlet/DOutlet)*(VOutlet²/2g) + FInlet*(LInlet/DInlet)*(VInlet²/2g)
        /// </summary>
        public Double WorkingFrictionHead => _workingFrictionHead;

        /// <summary>
        /// 工况动扬程(m)，计算公式：(VOutlet² - VInlet²)/2g
        /// 表示动能变化对应的扬程
        /// </summary>
        public Double WorkingDynamicHead => _workingDynamicHead;

        /// <summary>
        /// 工况静扬程(m)，计算公式：
        /// ((PresureOut - PresureIn)*1000)/(Rho * g)
        /// 其中压力单位kPa转换为Pa
        /// </summary>
        public Double WorkingStaticHead => _workingStaticHead;

        /// <summary>
        /// 工况总扬程(m)，计算公式：
        /// WorkingStaticHead + WorkingGeoHead + WorkingFrictionHead + WorkingDynamicHead
        /// </summary>
        public Double WorkingHead => _workingHead;

        /// <summary>
        /// 总压力(kPa)，直接取压差：PresureOut - PresureIn
        /// </summary>
        public Double TotalPressure => _totalPressure;

        /// <summary>
        /// 标况扬程(m)，按转速平方比例换算：
        /// (StpRotarySpeed/WorkRotarySpeed)² * WorkingHead
        /// </summary>
        public Double StpHead => _stpHead;

        /// <summary>
        /// 标况输入功率(kW)，按转速立方比例换算：
        /// (StpRotarySpeed/WorkRotarySpeed)³ * PowerIn
        /// </summary>
        public Double StpPowerIn => _stpPowerIn;

        /// <summary>
        /// 工况轴功率(kW)，计算公式：PowerIn * Efficiency/100
        /// </summary>
        public Double WorkingShaftPower => _workingShaftPower;

        /// <summary>
        /// 标况轴功率(kW)，按转速立方比例换算：
        /// (StpRotarySpeed/WorkRotarySpeed)³ * WorkingShaftPower
        /// </summary>
        public Double StpShaftPower => _stpShaftPower;

        /// <summary>
        /// 工况水功率(kW)，计算公式：
        /// WorkingHead * WorkQ * Rho * g /3600
        /// </summary>
        public Double WorkingWaterPower => _workingWaterPower;

        /// <summary>
        /// 工况泵效率(%)，计算公式：
        /// 100 * (WorkingWaterPower / WorkingShaftPower)
        /// </summary>
        public Double WorkingPumpEfficiency => _workingPumpEfficiency;

        /// <summary>
        /// 标况水功率(kW)，按转速立方比例换算：
        /// (StpRotarySpeed/WorkRotarySpeed)³ * WorkingWaterPower
        /// </summary>
        public Double StpWaterPower => _stpWaterPower;

        /// <summary>
        /// 标况泵效率(%)，计算公式：
        /// 100 * (StpWaterPower / StpShaftPower)
        /// </summary>
        public Double StpPumpEfficiency => _stpPumpEfficiency;

        /// <summary>
        /// 标况机组效率(%)，计算公式：
        /// 100 * (StpWaterPower / StpPowerIn)
        /// 包含电机和泵的整体效率
        /// </summary>
        public Double StpGroupEfficiency => _stpGroupEfficiency;

        public Double StpPresure => _stpPresure;

        /// <summary>
        /// 必需汽蚀余量NPSH(m)，计算公式：
        /// (Pabs_inlet)/(ρg) + VInlet²/2g - Pv/(ρg)
        /// 其中Pabs_inlet = Patm + PresureIn*1000
        /// </summary>
        public Double Npsh => _npsh;

        /// <summary>
        /// 汽蚀计算用扬程(m)，辅助计算参数
        /// </summary>
        public Double HeadForNpsh => _headForNpsh;
        #endregion

        private void PrintInputParameters(StringBuilder caculateProcess)
        {
            caculateProcess.AppendLine("********** 环境输入参数 **********");
            caculateProcess.AppendLine($"{"温度(TMedia)",-30}: {TMedia,15:F2} ℃");
            caculateProcess.AppendLine($"{"进口压力(PresureIn)",-30}: {PresureIn,15:F2} kPa");
            caculateProcess.AppendLine($"{"出口压力(PresureOut)",-30}: {PresureOut,15:F2} kPa");
            caculateProcess.AppendLine($"{"输入功率(PowerIn)",-30}: {PowerIn,15:F2} kW");
            caculateProcess.AppendLine($"{"工况流量(WorkQ)",-30}: {WorkQ,15:F2} m³/h");
            caculateProcess.AppendLine($"{"工况转速(WorkRotarySpeed)",-30}: {WorkRotarySpeed,15:F0} rpm");
            caculateProcess.AppendLine();

            caculateProcess.AppendLine("********** 设备参数 **********");
            caculateProcess.AppendLine($"{"进口高度(ZInlet)",-30}: {ZInlet,15:F2} m");
            caculateProcess.AppendLine($"{"出口高度(ZOutlet)",-30}: {ZOutlet,15:F2} m");
            caculateProcess.AppendLine($"{"进口直径(DInlet)",-30}: {DInlet,15:F2} mm");
            caculateProcess.AppendLine($"{"出口直径(DOutlet)",-30}: {DOutlet,15:F2} mm");
            caculateProcess.AppendLine($"{"进口粗糙度(KInlet)",-30}: {kInlet,15:F4} mm");
            caculateProcess.AppendLine($"{"出口粗糙度(KOutlet)",-30}: {kOutlet,15:F4} mm");
            caculateProcess.AppendLine($"{"进口管长(LInlet)",-30}: {LInlet,15:F2} m");
            caculateProcess.AppendLine($"{"出口管长(LOutlet)",-30}: {LOutlet,15:F2} m");
            caculateProcess.AppendLine($"{"标况转速(StpRotarySpeed)",-30}: {StpRotarySpeed,15:F0} rpm");
            caculateProcess.AppendLine($"{"电机效率(Efficiency)",-30}: {Efficiency,15:F1} %");
            caculateProcess.AppendLine($"{"重力加速度(g)",-30}: {g,15:F2} m/s²");
            caculateProcess.AppendLine($"{"大气压(pamp)",-30}: {pamp,15:F3} kPa");
            caculateProcess.AppendLine();
        }

        public void Calculate()
        {

            StringBuilder caculateProcess = new StringBuilder();

            try
            {
                caculateProcess.AppendLine("==================== 泵性能计算开始 ====================");

                caculateProcess.AppendLine($"计算时间：{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                caculateProcess.AppendLine("");
                PrintInputParameters(caculateProcess);
                // 基础参数计算
                _teta = (TMedia + 273.15) / 647.14;                //判断_teta是否是数字

                caculateProcess.AppendLine($"计算 Teta（无量纲温度）: (TMedia + 273.15) / 647.14 = {_teta}");

                _tau = 1 - _teta;
                caculateProcess.AppendLine($"计算 Tau （互补温度参数）: 1 - Teta = {_tau}");

                _rho = 322 * (1 + 1.99602 * Math.Pow(_tau, 1.0 / 3)
                    + 1.10123 * Math.Pow(_tau, 2.0 / 3)
                    + (-0.512506) * Math.Pow(_tau, 5.0 / 3)
                    + (-1.75263) * Math.Pow(_tau, 16.0 / 3)
                    + (-45.4485) * Math.Pow(_tau, 43.0 / 3)
                    + (-675615) * Math.Pow(_tau, 110.0 / 3));
                String formateRule = "322 × (1 + 1.99602 × Tau^(1/3) + 1.10123 × Tau^(2/3) - 0.512506 × Tau^(5/3) - 1.75263 × Tau^(16/3) - 45.4485 × Tau^(43/3) - 675615 × Tau^(110/3))";
                caculateProcess.AppendLine($"计算 Rho(介质密度): {formateRule} = {_rho}");

                // 面积计算
                _aInlet = (Math.PI / 4) * Math.Pow(DInlet, 2);
                caculateProcess.AppendLine($"计算 AInlet（进口截面积）: π/4 * DInlet² = {_aInlet}");

                _aOutlet = (Math.PI / 4) * Math.Pow(DOutlet, 2);
                caculateProcess.AppendLine($"计算 AOutlet（出口面积）: π/4 * DOutlet² = {_aOutlet}");

                // 相对粗糙度
                _eInlet = kInlet / DInlet;
                caculateProcess.AppendLine($"计算 EInlet（进口相对粗糙度）: KInlet/DInlet = {_eInlet}");

                _eOutlet = kOutlet / DOutlet;
                caculateProcess.AppendLine($"计算 EOutlet(出口相对粗糙度): KOutlet/DOutlet = {_eOutlet}");

                // 流速计算
                _vInlet = (WorkQ / 3600) / _aInlet;
                caculateProcess.AppendLine($"计算 VInlet (进口流速): (WorkQ/3600)/AInlet = {_vInlet}");

                _vOutlet = (WorkQ / 3600) / _aOutlet;
                caculateProcess.AppendLine($"计算 VOutlet（出口流速）: (WorkQ/3600)/AOutlet = {_vOutlet}");

                // 雷诺数
                _reyInlet = (DInlet * _vInlet) / 0.000001;
                caculateProcess.AppendLine($"计算 ReyInlet(进口雷诺数): (DInlet * VInlet)/0.000001 = {_reyInlet}");

                _reyOutlet = (DOutlet * _vOutlet) / 0.000001;
                caculateProcess.AppendLine($"计算 ReyOutlet(出口雷诺数): (DOutlet * VOutlet)/0.000001 = {_reyOutlet}");

                // 摩擦系数
                _fInlet = 1.0 / Math.Pow(1.8 * Math.Log10(6.9 / _reyInlet + Math.Pow((_eInlet / 3.7), 1.11)), 2);
                caculateProcess.AppendLine($"计算 FInlet（进口摩擦系数）: 1 / [1.8 × lg(6.9/ReyInlet + (EInlet/3.7)^1.11)]^2 = {_fInlet}");

                _fOutlet = 1.0 / Math.Pow(1.8 * Math.Log10(6.9 / _reyOutlet + Math.Pow((_eOutlet / 3.7), 1.11)), 2);
                caculateProcess.AppendLine($"计算 FOutlet（出口摩擦系数）: 1 / [1.8 × lg(6.9/ReyOutlet + (EOutlet/3.7)^1.11)]^2 = {_fOutlet}");

                // 标况流量
                _stpQ = (StpRotarySpeed / WorkRotarySpeed * 1.0) * WorkQ;
                caculateProcess.AppendLine($"计算 StpQ（转化后的标况流量）: (StpRotarySpeed/WorkRotarySpeed)*WorkQ = {_stpQ}");

                // 扬程计算
                _workingGeoHead = ZOutlet - ZInlet;
                caculateProcess.AppendLine($"计算 WorkingGeoHead（工况下的几何扬程）: ZOutlet - ZInlet = {_workingGeoHead}");

                _workingFrictionHead = _fOutlet * (LOutlet / 1.0) * Math.Pow(_vOutlet, 2.0) / ((DOutlet / 1.0) * 2 * g)
                    + _fInlet * (LInlet / 1.0) * Math.Pow(_vInlet, 2.0) / ((DInlet / 1.0) * 2 * g);
                caculateProcess.AppendLine($"计算 WorkingFrictionHead(工况下的摩擦损失扬程) : FOutlet * (LOutlet / 1.0) * VOutlet^2 / ((DOutlet / 1.0) * 2 * g) + FInlet * (LInlet / 1.0) * VInlet^2 / ((DInlet / 1.0) * 2 * g) = {_workingFrictionHead}");

                _workingDynamicHead = (Math.Pow(_vOutlet, 2.0) - Math.Pow(_vInlet, 2.0)) / (2 * g);
                caculateProcess.AppendLine($"计算 WorkingDynamicHead(工况下的摩擦损失扬程) :(VOutlet^2 - VInlet^2) / (2 * g)= {_workingDynamicHead}");

                _workingStaticHead = ((PresureOut - PresureIn) * 1000) / (_rho * g);
                caculateProcess.AppendLine($"计算 WorkingStaticHead(工况下的静失扬程) :((PresureOut - PresureIn) * 1000) / (_rho * g)= {_workingStaticHead}");

                _workingHead = _workingStaticHead + _workingGeoHead + _workingFrictionHead + _workingDynamicHead;
                caculateProcess.AppendLine($"计算 WorkingHead: WorkingStaticHead + WorkingGeoHead + WorkingFrictionHead + WorkingDynamicHead = {_workingHead}");

                _totalPressure = PresureOut - PresureIn;
                caculateProcess.AppendLine($"计算 TotalPressure（总压力）:PresureOut - PresureIn = {_totalPressure}");

                // 标况参数
                _stpHead = Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 2) * _workingHead;
                caculateProcess.AppendLine($"计算 StpHead（转化后标况扬程）:(StpRotarySpeed / WorkRotarySpeed * 1.0)^2 * WorkingHead;= {_stpHead}");

                _stpPowerIn = Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * PowerIn;
                caculateProcess.AppendLine($"计算 StpPowerIn（转化后的标况输入功率） : (StpRotarySpeed / WorkRotarySpeed * 1.0)^3)* PowerIn = {_stpPowerIn}");

                // 功率计算
                _workingShaftPower = PowerIn * Efficiency / 100.0;
                caculateProcess.AppendLine($"计算 WorkingShaftPower（工况轴功率） :PowerIn * Efficiency / 100.0= {_workingShaftPower}");

                _stpShaftPower = Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * _workingShaftPower;
                caculateProcess.AppendLine($"计算 StpShaftPower（转化后标况下的轴功率）:(StpRotarySpeed / WorkRotarySpeed * 1.0)^ 3 * WorkingShaftPower; = {_stpShaftPower}");

                _workingWaterPower = _workingHead * WorkQ * _rho * g / 3600;
                caculateProcess.AppendLine($"计算 WorkingWaterPower（工况下的水功率）: WorkingHead * WorkQ * Rho * g / 3600; = {_workingWaterPower}");

                // 效率计算
                _workingPumpEfficiency = 100.00 * (_workingWaterPower / _workingShaftPower);
                caculateProcess.AppendLine($"计算 WorkingPumpEfficiency（工况下的泵效率）：100.00 * (WorkingWaterPower /WorkingShaftPower)= {_workingPumpEfficiency}%");

                _stpWaterPower = Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * _workingWaterPower;
                caculateProcess.AppendLine($"计算 StpWaterPower（转化后标况下的水功率）：(StpRotarySpeed / WorkRotarySpeed * 1.0)^3 * WorkingWaterPower; = {_stpWaterPower}");

                _stpPumpEfficiency = 100.00 * (_stpWaterPower / _stpShaftPower);
                caculateProcess.AppendLine($"计算 StpPumpEfficiency（标况下的泵效率）:100.00 * (StpWaterPower /StpShaftPower) = {_stpPumpEfficiency}%");

                _stpGroupEfficiency = 100.0 * (_stpWaterPower / _stpPowerIn);
                caculateProcess.AppendLine($"计算 StpGroupEfficiency（标况下的几组效率）: 100.0 * StpWaterPower / StpPowerIn) = {_stpGroupEfficiency}%");

                _stpPresure = Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 2) * TotalPressure;
                caculateProcess.AppendLine($"计算 StpPresure（标况下的压力）:(StpRotarySpeed / WorkRotarySpeed * 1.0)^2 * TotalPressure = {StpPresure}%");



                // 汽蚀余量计算
                double h_s = (101325 + PresureIn * 1000) / (_rho * g);
                double area = Math.PI * Math.Pow(DInlet, 2) / 4;
                double v1 = (WorkQ / 3600) / area;
                double h_d = Math.Pow(v1, 2) / (2 * g);
                double p_v = 620.58 + 41.321 * TMedia + 1.6049 * Math.Pow(TMedia, 2)
                    + 0.0219 * Math.Pow(TMedia, 3) + 0.0003 * Math.Pow(TMedia, 4) + 0.0003 * Math.Pow(TMedia, 5);
                double h_v = p_v / (_rho * g);
                _npsh = h_s - ZInlet + h_d - h_v;  // 修正公式
                caculateProcess.AppendLine($"计算 Npsh = {_npsh}");

                _headForNpsh = (PresureIn * 1000 - 3160 * pamp) / _rho * g;
                caculateProcess.AppendLine($"计算 HeadForNpsh = {_headForNpsh}");

                caculateProcess.AppendLine("======== 计算完成 ========");

            }
            catch
            {
                LogHelper.LoggerMsg(LogLevel.Error, "Calculate 指标计算错误，详情:" + caculateProcess.ToString());
            }
            finally
            {
                Debug.WriteLine(caculateProcess.ToString());
            }
        }


        #region 计算公式
        /*
        /// <summary>
        /// 进口面积计算公式
        /// </summary>
        const String express_AInlet = " (Math.PI / 4) *  Math.Pow((DInlet / 1000),2)";



        public Double AInlet
        {
            get
            {
                //dynamic expandoObject = new ExpandoObject();
                //expandoObject.DInlet = this.DInlet;
                //var result = Eval.Execute<Double>(express_AInlet, expandoObject);
                //return (Double)result;
                return (Math.PI / 4) * Math.Pow((DInlet ), 2);
            }
        }


        /// <summary>
        /// 出口面积计算公式
        /// </summary>

        public Double AOutlet
        {
            get
            {
                return (Math.PI / 4) * Math.Pow((DOutlet), 2);
            }
        }

        /// <summary>
        /// 进口相对粗糙度
        /// </summary>

        public Double EInlet
        {
            get
            {
                return KInlet / DInlet;
            }
        }


        /// <summary>
        /// 出口相对粗糙度
        /// </summary>

        public Double EOutlet
        {
            get
            {
                return KOutlet / DOutlet;
            }
        }


        /// <summary>
        ///  进口流速
        /// </summary>
        public Double VInlet
        {
            get
            {
                return (WorkQ / 3600) / AInlet;
            }
        }


        /// <summary>
        /// 出口流速
        /// </summary>
        //const String express_VOutlet = "(Q/3600)/ AOutlet";

        public Double VOutlet
        {
            get
            {
                return (WorkQ / 3600) / AOutlet;
            }
        }

        /// <summary>
        ///  进口雷诺数
        /// </summary>

        public Double ReyInlet
        {
            get
            {
                return (DInlet * VInlet) / 0.000001;
            }
        }

        /// <summary>
        ///  出口雷诺数
        /// </summary>


        public Double ReyOutlet
        {
            get
            {
                return (DOutlet * VOutlet) / 0.000001;
            }
        }


        /// <summary>
        /// 进口摩擦系数
        /// </summary>
        //const String express_FInlet = "1/Math.Pow(1.8*Math.Log10(6.9/ReyInlet +Math.Pow((EInlet / 3.7),1.11)),2)";
        //const String express_FInlet = "1/Math.Pow(1.8*Math.Log(6.9/ReyInlet +Math.Pow((EInlet / 3.7),1.11)),2)";


        public Double FInlet
        {
            get
            {
                return 1.0 / Math.Pow(1.8 * Math.Log10(6.9 / ReyInlet + Math.Pow((EInlet / 3.7), 1.11)), 2);
            }
        }

        /// <summary>
        /// 出口摩擦系数
        /// </summary>
        //const String express_FOutlet = "1 / Math.Pow(1.8 * Math.Log( ( (6.9 / ReyOutlet)  + Math.Pow((EOutlet / 3.7),1.11) ),2))";
        //const String express_FOutlet = "1/Math.Pow(1.8*Math.Log10(6.9/ReyOutlet +Math.Pow((EOutlet / 3.7),1.11)),2)";
        public Double FOutlet
        {
            get
            {
                return 1.0 / Math.Pow(1.8 * Math.Log10(6.9 / ReyOutlet + Math.Pow((EOutlet / 3.7), 1.11)), 2);
            }
        }


        const String express_Tau = "1 - Teta";
        public Double Tau
        {
            get
            {
                return 1 - Teta;
            }
        }
        const String express_Teta = "(TMedia + 273.15) / 647.14";
        public Double Teta
        {
            get
            {
                return (TMedia + 273.15) / 647.14;
            }
        }


        const String express_Rho = "322 * (1 + 1.99602 * Math.Pow(Tau,1.0/3) + 1.10123* Math.Pow(Tau,2.0/3) + (-0.512506)*Math.Pow(Tau,5.0/3) + (-1.75263)*Math.Pow(Tau,16.0/3) + (-45.4485)*Math.Pow(Tau,43.0/3) + (-675615)*Math.Pow(Tau,110.0/3))";

        public Double Rho
        {
            get
            {
                return 322 * (1 + 1.99602 * Math.Pow(Tau, 1.0 / 3) + 1.10123 * Math.Pow(Tau, 2.0 / 3) + (-0.512506) * Math.Pow(Tau, 5.0 / 3) + (-1.75263) * Math.Pow(Tau, 16.0 / 3) + (-45.4485) * Math.Pow(Tau, 43.0 / 3) + (-675615) * Math.Pow(Tau, 110.0 / 3));
            }
        }


        /// <summary>
        /// 标况流量
        /// </summary>
        
        public Double StpQ
        {
            get
            {
                return (StpRotarySpeed / WorkRotarySpeed * 1.0) * workQ;
            }
        }

        /// <summary>
        /// 工况下的静扬程
        /// </summary>  
        const String express_WorkingStaticHead = "((PresureOut - PresureIn) * 100000) / (Rho * g)";
        public Double WorkingStaticHead
        {
            get
            {
                return ((PresureOut - PresureIn) * 1000) / (Rho * g);
            }
        }


        /// <summary>
        /// 工况下的几何扬
        /// </summary>
       
        public Double WorkingGeoHead
        {
            get
            {
                return ZOutlet - ZInlet;
            }
        }

        /// <summary>
        /// 工况下的摩擦损失扬程
        /// </summary>
        const String express_WorkingFrictionHead = "FOutlet * (LOutlet / 1000) * Math.Pow(VOutlet, 2.0) / ((DOutlet / 1000.0f) * 2 * g) + FInlet * (LInlet / 1000) * Math.Pow(VInlet, 2.0) / ((DInlet / 1000) * 2 * g)";

        public Double WorkingFrictionHead
        {
            get
            {
                return FOutlet * (LOutlet /1.0 ) * Math.Pow(VOutlet, 2.0) / ((DOutlet / 1.0) * 2 * g) + FInlet * (LInlet / 1.0) * Math.Pow(VInlet, 2.0) / ((DInlet / 1.0) * 2 * g);
            }
        }

        /// <summary>
        /// 工况下的动扬程
        /// </summary>
        const String express_WorkingDynamicHead = "(Math.Pow(VOutlet, 2.0) - Math.Pow(VInlet, 2.0)) / (2 * g)";
        public Double WorkingDynamicHead
        {
            get
            {
                return (Math.Pow(VOutlet, 2.0) - Math.Pow(VInlet, 2.0)) / (2 * g);
            }
        }

        /// <summary>
        /// 工况下的静扬程
        /// </summary>  
        const String express_WorkingStaticHead = "((PresureOut - PresureIn) * 100000) / (Rho * g)";

        /// <summary>
        /// 工况静扬程
        /// </summary>
        public Double WorkingStaticHead
        {
            get
            {
               
                return ((PresureOut - PresureIn) * 1000) / (Rho * g);
            }
        }

        /// <summary>
        /// 计算工况扬程
        /// </summary>
        const String express_WorkingHead = "WorkingStaticHead + WorkingGeoHead + WorkingFrictionHead + WorkingDynamicHead";

        /// <summary>
        /// 工况扬程
        /// </summary>
        public Double WorkingHead
        {
            get
            {
                return WorkingStaticHead + WorkingGeoHead + WorkingFrictionHead + WorkingDynamicHead;
            }
        }

        /// <summary>
        /// 总压力
        /// </summary>
        public Double TotalPressure
        {
            get
            {
                //return (Rho * g) * WorkingHead / 1000.0f;
                return PresureOut - PresureIn;
            }
        }


        /// <summary>
        /// 标况扬程
        /// </summary>
        const String express_StpHead = " Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 2) * WorkingHead";

        /// <summary>
        /// 标况扬程
        /// </summary>
        public Double StpHead
        {
            get
            {
                return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 2) * WorkingHead;
            }
        }

        /// <summary>
        /// 标况下的压力
        /// </summary>
        public Double StpPresure
        {
            get
            {
                return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 2) * TotalPressure;
            }
        }

        /// <summary>
        /// 输入功率（标况下的）
        /// </summary>
       
        public Double StpPowerIn
        {
            get
            {
                return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * PowerIn;
            }
        }

        /// <summary>
        /// 工况轴功率
        /// </summary>
       
        public Double WorkingShaftPower
        {
            get
            {
                return PowerIn * Efficiency / 100.0;
            }
        }

        /// <summary>
        /// 标况轴功率
        /// </summary>
       
        public Double StpShaftPower
        {
            get
            {
                return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * WorkingShaftPower;
            }
        }

        /// <summary>
        /// 工况下的水功率
        /// </summary>
       
        public Double WorkingWaterPower
        {
            get
            {
                return WorkingHead * workQ * Rho * g / 3600;
            }
        }

        /// <summary>
        /// 工况下的效率
        /// </summary>
        
        public Double WorkingPumpEfficiency
        {
            get
            {
                return 100.00 * (WorkingWaterPower / WorkingShaftPower);
            }
        }


        /// <summary>
        /// 标况下的水功率
        /// </summary>
      
        public Double StpWaterPower
        {
            get
            {
                return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * WorkingWaterPower;
            }
        }


        /// <summary>
        /// 泵效率（标况下的），泵效率为水功率除以轴功率(返回百分比)
        /// </summary>
       
        public Double StpPumpEfficiency
        {
            get
            {
                return 100.00 * (StpWaterPower / StpShaftPower);
            }
        }


        /// <summary>
        /// 机组效率（标况下的）
        /// </summary>
      
        public Double StpGroupEfficiency
        {
            get
            {
                return 100.0 * (StpWaterPower / StpPowerIn);
            }
        }

        /// <summary>
        /// 汽蚀余量计算
        /// </summary>
        public Double Npsh
        {
            get
            {
                double h_s = (101325 + presureIn*1000) / (Rho * g);

                double area = Math.PI * Math.Pow(DInlet, 2)/4;
                double v1 = (WorkQ / 3600) / area;
                double h_d = Math.Pow(v1, 2) /(2 * g);

                double p_v = 620.58 + 41.321 * TMedia + 1.6049 * Math.Pow(TMedia, 2) + 0.0219 * Math.Pow(TMedia, 3) +
                    0.0003 * Math.Pow(TMedia, 4) + 0.0003 * Math.Pow(TMedia, 5);
                double h_v = p_v / (Rho*g);
     
                return h_s+h_d+h_v;
            }
        }

        public Double HeadForNpsh
        {
            get
            {
                return (PresureIn*1000 - 3160 * pamp) / Rho * g;
            }
        }

        public double KInlet { get => kInlet; set => kInlet = value; }
        public double KOutlet { get => kOutlet; set => kOutlet = value; }
        */
        #endregion

        #region 注释的函数
        /*
        /// <summary>
        /// 标况扬程
        /// </summary>
        /// <returns></returns>
        public Double caculateStpHead()
        {
            return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 2) * this.caculateWorkingHead();
        }

        /// <summary>
        /// 工况轴功率
        /// </summary>
        /// <returns></returns>
        public Double caculateWorkingShaftPower()
        {
            return this.PowerIn * this.Efficiency;
        }

        /// <summary>
        /// 标况轴功率
        /// </summary>
        /// <returns></returns>
        public Double caculateStpShaftPower()
        {
            return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * this.caculateWorkingShaftPower();
        }

        /// <summary>
        /// 工况下的水功率
        /// </summary>
        /// <returns></returns>
        private Double caculateWorkWaterPower()
        {
            return this.caculateWorkingHead() * this.WorkingFlow * rho * g / 3600;
        }

        /// <summary>
        /// 标况下的水功率
        /// </summary>
        /// <returns></returns>
        private Double caculateStpWaterPower()
        {
            return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * this.caculateWorkWaterPower();
        }

        /// <summary>
        /// 泵效率（标况下的），泵效率为水功率除以轴功率(返回百分比)
        /// </summary>
        /// <returns></returns>
        public Double caculateStpPumpEfficiency()
        {
            return 100.00 * (this.caculateStpWaterPower() / this.caculateStpShaftPower());
        }

        /// <summary>
        /// 输入功率（标况下的）
        /// </summary>
        /// <returns></returns>
        private Double caculateStpPowerIn()
        {
            return Math.Pow((StpRotarySpeed / WorkRotarySpeed * 1.0), 3) * this.PowerIn;
        }
        */
        #endregion

        #region 通过函数计算出来的参数，暂时注释
        /*
private Double Teta {
get
{

 var result = Eval.Execute<float>(express_Teta);
 Console.WriteLine(result);
 Console.ReadLine();
 this.Teta
 return 0.0f;
}            

}

private Double Tau { get => 1 - Teta; }

//密度
public Double Rho { get => 322 * (1 + 1.99602f * Math.Pow(tau, 1 / 3.0) + 1.10123 * Math.Pow(tau, (2 / 3.0f)) + (-0.512506) * Math.Pow(tau, (5.0f / 3)) + (-1.75263) * Math.Pow(tau, (16 / 3.0f)) + (-45.4485) * Math.Pow(tau, (43 / 3.0f)) + (-675615) * Math.Pow(tau, (110 / 3.0f))); }


/// <summary>
/// 进口面积
/// </summary>
Double AInlet { get => Math.Pow((Math.PI / 4) * (DInlet / 1000), 2); }

/// <summary>
/// 出口面积
/// </summary>
Double AOutlet { get => Math.Pow((Math.PI / 4) * (DOutlet / 1000), 2); }

/// <summary>
/// 相对进口粗糙度
/// </summary>
Double EInlet { get => kInlet / this.DInlet; }

/// <summary>
/// 相对出口粗糙度
/// </summary>
Double EOutlet { get => kOutlet / this.DOutlet; }

/// <summary>
/// 出口流速
/// </summary>
public double VOutlet { get => (WorkingFlow / 3600) / AInlet; }
/// <summary>
/// 进口流速
/// </summary>
public double VInlet { get => (WorkingFlow / 3600) / AOutlet; }

/// <summary>
/// 进口雷诺数
/// </summary>
private Double ReyInlet { get => this.DInlet / 1000 * this.VInlet / 0.000001; }


/// <summary>
///  出口雷诺数
/// </summary>
private Double ReyOutlet { get => this.DOutlet / 1000 * this.VOutlet / 0.000001; }


/// <summary>
/// 出口摩擦系数
/// </summary>
private double FOutlet { get => 1 / Math.Pow((1.8 * Math.Log((6.9 / ReyOutlet) + Math.Pow((EOutlet / 3.7), 1.11))), 2); }
/// <summary>
/// 入口摩擦系数
/// </summary>
private double FInlet { get => 1 / Math.Pow((1.8 * Math.Log((6.9 / ReyInlet) + Math.Pow((EInlet / 3.7), 1.11))), 2); }





/// <summary>
/// 计算工况的静扬程
/// </summary>
private Double caculateWorkingStaticHead()
{
return ((PressureOut - PressureIn) * 100000) / (rho * g);
}

/// <summary>
/// 计算工况的几何扬程
/// </summary>
private Double caculateWorkingGeoHead()
{
return ZOutlet - ZInlet;
}

/// <summary>
/// 计算工况的摩擦损失扬程
/// </summary>
private Double caculateWorkingFrictionHead()
{

return FOutlet * (LOutlet / 1000) * Math.Pow(VOutlet, 2.0) / ((DOutlet / 1000.0f) * 2 * g) + FInlet * (LInlet / 1000) * Math.Pow(VInlet, 2.0) / ((DInlet / 1000) * 2 * g);
}

/// <summary>
/// 计算工况的动扬程
/// </summary>
private Double caculateWorkingDynamicHead()
{
return (Math.Pow(VOutlet, 2.0) - Math.Pow(VInlet, 2.0) / (2 * g));
}

/// <summary>
/// 计算工况扬程
/// </summary>
public Double caculateWorkingHead()
{
return this.caculateWorkingStaticHead() + this.caculateWorkingGeoHead() + this.caculateWorkingFrictionHead() + this.caculateWorkingDynamicHead();
}

/// <summary>
/// 标况流量
/// </summary>
/// <returns></returns>
public Double caculateStpFlow()
{
return (StpRotarySpeed / WorkRotarySpeed * 1.0) * workQ;
}        



*/
        #endregion

        public void setplcEnvData(Double tMedia, Double presureIn, Double presureOut, Double powerIn, Double workQ, int workRotarySpeed)
        {
            this.TMedia = tMedia;
            this.PresureIn = presureIn;
            this.PresureOut = presureOut;
            this.PowerIn = powerIn;
            this.WorkQ = workQ;
            this.WorkRotarySpeed = workRotarySpeed;
        }


       
        public static Double[] Solve(Double[] Q, Double[] target)
        {
            if (Q.Length == 0 || target.Length == 0 || Q.Length != target.Length)
            {
                return null;
            }
            Double[] result = new Double[5] { 0,0,0,0,0};
            if (Q.Length == 1)
            {
                result[4] = target[0];
            }


            int length = Q.Length;
            DenseMatrix matrixA = new DenseMatrix(5, 5);
            for (int i = 0; i < matrixA.RowCount; i++)
            {
                for (int j = 0; j < matrixA.ColumnCount; j++)
                {
                    matrixA[i, j] = sumQ(Q, (i + j));
                }
            }
            DenseMatrix matrixB = new DenseMatrix(5, 1);
            for (int i = 0; i < matrixB.RowCount; i++)
            {
                matrixB[i, 0] = sumQT(Q, target, i);
            }
            //var qr = matrixA.QR();
            //Matrix<Double> resultLU = qr.Solve(matrixB);

            Matrix<Double> resultLU = matrixA.LU().Solve(matrixB);

            //var resultQR= matrixA.QR().Solve(matrixB);

            for (int i = 4, j = 0; i >= 0; i--, j++)
            {
                result[i] = resultLU[j, 0];
            }

            return result;
        }

        private static double sumQT(double[] q, double[] target, int pow)
        {
            double sum = 0.0f;
            for (int i = 0; i < q.Length; i++)
            {
                sum += target[i] * Math.Pow(q[i], pow);
            }
            return sum;
        }

        private static double sumQ(double[] q, int pow)
        {
            double sum = 0.0f;
            for (int i = 0; i < q.Length; i++)
            {
                sum += Math.Pow(q[i], pow);
            }
            return sum;
        }

        public static Double CaculateValue(Double q, Double[] param)
        {
            return param[0] * Math.Pow(q, 4) + param[1] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[3] * Math.Pow(q, 1) + param[4] * Math.Pow(q, 0);
            //return param[4] * Math.Pow(q, 4) + param[3] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[1] * Math.Pow(q, 1) + param[0] * Math.Pow(q, 0);
        }



        public static Double[] CaculateParams(Double[] qlist, Double[] ylist)
        {
            Double[] paramH = Solve(qlist, ylist);
            return paramH;
        }

        public static Double[] SolveEquations(Double[] paramsData)
        {
            Polynomial polynomial = new Polynomial(paramsData);

            // Find roots of the polynomial equation
            Complex[] roots = polynomial.Roots();
            List<Double> resultList = new List<double>();

            for (int i = 0; i < roots.Length ; i++)
            {
                if( roots[i].IsReal())
                { resultList.Add(roots[i].Real); }
                
            }
            return resultList.ToArray();
        }

        public static List<Double[]> SolveEquations(Double a, Double b, Double minX, Double maxX, Double[] param)
        {
            // double rate = ratedY / ratedX;

            int seg = 10;



            double[] result = CanonicalAlgorithm.SolveEquations(new double[] { param[4] - b, param[3] - a, param[2], param[1], param[0] });

            for (int i = 0; i < result.Length; i++)
            {
                double x = result[i];
                double ret = param[0] * Math.Pow(x, 4) + param[1] * Math.Pow(x, 3) + param[2] * Math.Pow(x, 2) + (param[3] - a) * Math.Pow(x, 1) + (param[4] - b);
                System.Console.WriteLine("ret = {0}", ret);
            }

            List<Double[]> list = new List<double[]>();
            if (result != null)
            {
                for (int i = 0; i < result.Length; i++)
                {
                    if ((result[i] - minX) > double.Epsilon && (maxX - result[i]) > double.Epsilon)
                    {
                        list.Add(new Double[] { result[i], a * result[i] + b });
                    }
                }

            }
            return list;
            
        }

      


        public static IDictionary<String,Object> example()
        {
            Double zInlet = 0.0f;
            Double zOutlet = 0.0f;
            Double kInlet = 0.05f;
            Double kOutlet = 0.05f;
            Double dInlet = 81.0f;
            Double dOutlet = 81.0f;
            Double lInlet = 400.0f;
            Double lOutlet = 400.0f;
            Double efficiency = 90.0f;//??
            int stpRotarySpeed = 4000;//???

            Dictionary<String, Object> dic = new Dictionary<String, Object>();

            Double[,] datas = new Double[,]
            {
                //1.测量的流量值
                //2.输入值进口压力
                //3.输出值出口压力
                //4.电压
                //5.电流
                //6.功率
                //7.转速
                //8.温度
                //{ 0,   0,   1.758895,    0,   0 ,  1008.888137, 3999.8,  19.870001 },
                {3.612153 ,   0 ,  1.748751 ,    0,   0  , 1158.143406, 3999   , 20.063147 },
                {7.498365,   0  , 1.737631  ,   0 ,  0 ,  1317.43434 , 3999.9 ,  19.973012},
                {11.182576,   0 ,  1.720122 ,    0 ,  0  , 1464.996243, 4000.1 , 19.90863},
                {15.031077,   0 ,  1.708246 ,    0 ,  0 ,  1624.563531, 4000.6 , 19.921507},
                {18.644812,   0 ,  1.707075 ,    0 ,  0 ,  1784.613132, 3999.9 , 19.870001},
                {22.176107 ,  0 ,  1.703125 ,    0 ,  0 ,  1936.297499, 4000.3 , 19.876439},
                {26.116644,   0 ,  1.694688 ,    0 ,  0 ,  2084.386691, 4000.8,  19.812056},
                {29.948536,   0 ,  1.684446 ,   0 ,  0 ,  2242.862603, 3999.5 , 19.676855},
                {33.613707 ,  0 ,  1.669765 ,    0 ,  0 ,  2379.589111, 4000.6,  19.676855},
                {37.286358 ,  0 ,  1.638259 ,    0 ,  0 ,  2485.674208, 4000  ,  19.676855},
                {41.062103 ,  0 ,  1.589561 ,    0 ,  0 ,  2569.233127, 3999.3 , 19.805618},
                {44.696009 ,  0 ,  1.522232 ,    0 ,  0 ,  2615.767117, 4000.3 , 19.831371},
                {48.478684 ,  0 ,  1.435272 ,    0 ,  0 ,  2633.687148, 3999.1 , 19.870001 },
                {52.545757 ,  0 ,  1.338924 ,    0 ,  0 ,  2656.621311, 4000.7 , 19.850686},
                {56.050962 ,  0 ,  1.227993 ,    0 ,  0 ,  2629.186984, 3999.4 , 19.824933},
                {59.73587 ,   0 ,  1.110966 ,    0 ,  0 ,  2578.679932, 4000.1 , 19.805618},
                {63.44008,    0 ,  0.978186 ,    0 ,  0 ,  2538.763183, 4000.2,  19.831371},
                {67.250777 ,  0 ,  0.847088 ,    0 ,  0  , 2465.42825,  3999.7 , 19.870001},
                {70.599366,   0 ,  0.699773 ,    0 ,  0 ,  2336.612169, 3999.7 , 19.805618 },
                {74.167113 ,  0 ,  0.563238 ,    0 ,  0 ,  2242.949938, 4000 ,   19.870001},
                //{78.391573,   0 ,  0.371095 ,    0 ,  0 ,  0 ,  3999.4,  19.870001 },
             };



            ArrayList list = new ArrayList();
            int count = datas.GetLength(0);
            Double[] Q = new Double[count];
            Double[] H = new Double[count];
            Double[] P = new Double[count];
            Double[] E = new Double[count];
            for (int i = 0; i < count; i++)
            {
                Data d = new Data();
                d.Liuliang = datas[i, 0];
                d.Jkyl = datas[i, 1];
                d.Ckyl = datas[i, 2];
                d.Dianliu = datas[i, 3];
                d.Dianya = datas[i, 4];
                d.Gonglv = datas[i, 5];
                //data.Yangcheng = datas[i, 6];
                d.Zhuansu = datas[i, 6];
                d.Wendu = datas[i, 7];
                
                CanonicalAlgorithm algo = new CanonicalAlgorithm(zInlet, zOutlet, kInlet, kOutlet, dInlet, dOutlet, lInlet, lOutlet, efficiency, stpRotarySpeed);
                algo.setplcEnvData(d.Wendu, d.Jkyl, d.Ckyl, d.Gonglv, d.Liuliang, (int)d.Zhuansu);
                d.Yangcheng = algo.WorkingHead;
                d.Gonglv = algo.WorkingShaftPower;
                d.Xiaolv = algo.WorkingPumpEfficiency;
                list.Add(d);
                Q[i] = d.Liuliang;
                H[i] = d.Yangcheng;
                P[i] = d.Gonglv;
                E[i] = d.Xiaolv;
            }
            Double[] paramH = Solve(Q, H);
            Double[] paramP = Solve(Q, P);
            Double[] paramE = Solve(Q, E);
            dic.Add("sourceData", list);
            dic.Add("paramH", paramH);
            dic.Add("paramP", paramP);
            dic.Add("paramE", paramE);
            return dic;

        }

        static void Main(string[] args)
        {
            Double zInlet  =  0.0f;
            Double zOutlet =  0.0f;
            Double kInlet  =  0.05f;
            Double kOutlet =  0.05f;
            Double dInlet  =  81.0f;
            Double dOutlet =  81.0f;
            Double lInlet  =  400.0f;
            Double lOutlet =  400.0f;
            Double efficiency = 90.0f;//??
            int stpRotarySpeed = 4000;//???

            Double[,] datas = new Double[,]
            {
                //1.测量的流量值
                //2.输入值进口压力
                //3.输出值出口压力
                //4.电压
                //5.电流
                //6.功率
                //7.转速
                //8.温度
                //{ 0,   0,   1.758895,    0,   0 ,  1008.888137, 3999.8,  19.870001 },
                {3.612153 ,   0 ,  1.748751 ,    0,   0  , 1158.143406, 3999   , 20.063147 },
                {7.498365,   0  , 1.737631  ,   0 ,  0 ,  1317.43434 , 3999.9 ,  19.973012},
                {11.182576,   0 ,  1.720122 ,    0 ,  0  , 1464.996243, 4000.1 , 19.90863},
                {15.031077,   0 ,  1.708246 ,    0 ,  0 ,  1624.563531, 4000.6 , 19.921507},
                {18.644812,   0 ,  1.707075 ,    0 ,  0 ,  1784.613132, 3999.9 , 19.870001},
                {22.176107 ,  0 ,  1.703125 ,    0 ,  0 ,  1936.297499, 4000.3 , 19.876439},
                {26.116644,   0 ,  1.694688 ,    0 ,  0 ,  2084.386691, 4000.8,  19.812056},
                {29.948536,   0 ,  1.684446 ,   0 ,  0 ,  2242.862603, 3999.5 , 19.676855},
                {33.613707 ,  0 ,  1.669765 ,    0 ,  0 ,  2379.589111, 4000.6,  19.676855},
                {37.286358 ,  0 ,  1.638259 ,    0 ,  0 ,  2485.674208, 4000  ,  19.676855},
                {41.062103 ,  0 ,  1.589561 ,    0 ,  0 ,  2569.233127, 3999.3 , 19.805618},
                {44.696009 ,  0 ,  1.522232 ,    0 ,  0 ,  2615.767117, 4000.3 , 19.831371},
                {48.478684 ,  0 ,  1.435272 ,    0 ,  0 ,  2633.687148, 3999.1 , 19.870001 },
                {52.545757 ,  0 ,  1.338924 ,    0 ,  0 ,  2656.621311, 4000.7 , 19.850686},
                {56.050962 ,  0 ,  1.227993 ,    0 ,  0 ,  2629.186984, 3999.4 , 19.824933},
                {59.73587 ,   0 ,  1.110966 ,    0 ,  0 ,  2578.679932, 4000.1 , 19.805618},
                {63.44008,    0 ,  0.978186 ,    0 ,  0 ,  2538.763183, 4000.2,  19.831371},
                {67.250777 ,  0 ,  0.847088 ,    0 ,  0  , 2465.42825,  3999.7 , 19.870001},
                {70.599366,   0 ,  0.699773 ,    0 ,  0 ,  2336.612169, 3999.7 , 19.805618 },
                {74.167113 ,  0 ,  0.563238 ,    0 ,  0 ,  2242.949938, 4000 ,   19.870001},
                //{78.391573,   0 ,  0.371095 ,    0 ,  0 ,  0 ,  3999.4,  19.870001 },
             };



            ArrayList list = new ArrayList();
            int count = datas.GetLength(0);
            Double[] Q = new Double[count];
            Double[] H = new Double[count];
            Double[] P = new Double[count];
            Double[] E = new Double[count];
            for (int i = 0; i < count; i++)
            {
                Data d = new Data();
                d.Liuliang = datas[i, 0];
                d.Jkyl = datas[i, 1];
                d.Ckyl = datas[i, 2];
                d.Dianliu = datas[i, 3];
                d.Dianya = datas[i, 4];
                d.Gonglv = datas[i, 5];
                //data.Yangcheng = datas[i, 6];
                d.Zhuansu = datas[i, 6];
                d.Wendu = datas[i, 7];
                list.Add(d);
                CanonicalAlgorithm algo = new CanonicalAlgorithm(zInlet, zOutlet, kInlet, kOutlet, dInlet, dOutlet, lInlet, lOutlet, efficiency, stpRotarySpeed);
                algo.setplcEnvData(d.Wendu, d.Jkyl, d.Ckyl, d.Gonglv, d.Liuliang, (int)d.Zhuansu);
                Q[i] = d.Liuliang;
                H[i] = algo.WorkingHead;
                P[i] = algo.WorkingShaftPower;
                
            }

            Solve(Q, H);

            Data data = (Data)list[2];
            CanonicalAlgorithm algorithm = new CanonicalAlgorithm(zInlet, zOutlet, kInlet, kOutlet, dInlet, dOutlet, lInlet, lOutlet, efficiency, stpRotarySpeed);
            algorithm.setplcEnvData(data.Wendu, data.Jkyl, data.Ckyl, data.Gonglv, data.Liuliang, (int)data.Zhuansu);
            System.Console.WriteLine("产品输入参数：");
            System.Console.WriteLine("进口取压高度(zInlet):{0}",zInlet);
            System.Console.WriteLine("出口取压高度(zOutlet):{0}", zOutlet);
            System.Console.WriteLine("进口摩擦系数(kInlet):{0}", kInlet);
            System.Console.WriteLine("出口摩擦系数(kOutlet):{0}", kOutlet);
            System.Console.WriteLine("进口直径(dInlet):{0}", dInlet);
            System.Console.WriteLine("出口直径(dOutlet):{0}", dOutlet);
            System.Console.WriteLine("进口取压长度(kInlet):{0}", lInlet);
            System.Console.WriteLine("出口取压长度(kOutlet):{0}", lOutlet);
            System.Console.WriteLine("额定效率(efficiency):{0}", efficiency);
            System.Console.WriteLine("额定转速(stpRotarySpeed):{0}\r", stpRotarySpeed);

            System.Console.WriteLine("环境输入参数");
            System.Console.WriteLine("温度(tMedia):{0}", data.Wendu);
            System.Console.WriteLine("进口压力(presureIn):{0}", data.Jkyl);
            System.Console.WriteLine("出口压力(presureOut):{0}", data.Ckyl);
            System.Console.WriteLine("工况功率(powerIn):{0}", data.Gonglv);
            System.Console.WriteLine("工况流量(workQ):{0}", data.Liuliang);
            System.Console.WriteLine("工况转速(workRotarySpeed):{0}\r", data.Zhuansu);

            System.Console.WriteLine("计算参数");
            System.Console.WriteLine("进口面积(A_inlet)  :{0}" ,algorithm.AInlet);
            System.Console.WriteLine("出口面积(A_outlet)  :{0}" , algorithm.AOutlet);
            System.Console.WriteLine("进口流速(VInlet) :{0} " ,   algorithm.VInlet);
            System.Console.WriteLine("出口流速(VOutlet) :{0} " ,  algorithm.VOutlet);


            System.Console.WriteLine("(Teta) :{0} " , algorithm.Teta);
            System.Console.WriteLine("(Rho) :{0} " , algorithm.Rho);
            System.Console.WriteLine("(Tau) :{0}" , algorithm.Tau);

            System.Console.WriteLine("进口相对粗糙度(EInlet)  :  {0}" , algorithm.EInlet);
            System.Console.WriteLine("出口相对粗糙度(EOutlet)  : {0}" , algorithm.EOutlet);
            System.Console.WriteLine("进口摩擦力系数(FInlet)  :  {0}" , algorithm.FInlet);
            System.Console.WriteLine("出口摩擦力系数(FOutlet)  : {0}" , algorithm.FOutlet);
            System.Console.WriteLine("进口雷诺数(ReyInlet) : {0} " , algorithm.ReyInlet);
            System.Console.WriteLine("进口雷诺数(ReyOutlet) :{0} " , algorithm.ReyOutlet);

            System.Console.WriteLine("标况流量(StpQ)  :  {0}",                           algorithm.StpQ);
            System.Console.WriteLine("工况静扬程(WorkingStaticHead)  : {0}",             algorithm.WorkingStaticHead);
            System.Console.WriteLine("工况集合扬程(WorkingGeoHead)  :  {0}",             algorithm.WorkingGeoHead);
            System.Console.WriteLine("工况下的摩擦损失扬程(WorkingFrictionHead)  : {0}", algorithm.WorkingFrictionHead);
            System.Console.WriteLine("工况下的动扬程(WorkingDynamicHead) : {0} ",        algorithm.WorkingDynamicHead);
            System.Console.WriteLine("工况扬程(WorkingHead) :{0} ",                      algorithm.WorkingHead);
            System.Console.WriteLine("标况扬程(StpHead) :{0} ",                          algorithm.StpHead);

            System.Console.WriteLine("标况下的功率(StpPowerIn)  :  {0}", algorithm.StpPowerIn);
            System.Console.WriteLine("工况下的轴功率(WorkingShaftPower)  : {0}", algorithm.WorkingShaftPower);
            System.Console.WriteLine("标况下的轴功率(StpShaftPower)  :  {0}", algorithm.StpShaftPower);
            System.Console.WriteLine("工况下的水功率(WorkingWaterPower)  : {0}", algorithm.WorkingWaterPower);
            System.Console.WriteLine("标况下的动扬程(WorkingWaterPower) : {0} ", algorithm.WorkingWaterPower);
            System.Console.WriteLine("标况下的泵效率(StpPumpEfficiency) :{0} ", algorithm.StpPumpEfficiency);
            System.Console.WriteLine("标况下的机组效率(StpGroupEfficiency) :{0} ", algorithm.StpGroupEfficiency);

            //ExcelUtil excel = new ExcelUtil();
            //excel.exportExcel();

            //System.Console.ReadLine();
        }
    }
}
